package mrusanov.season

import mrusanov.league.{League, LeagueInfoSystem, LeagueSystem}
import mrusanov.team._
import mrusanov.tournament.{MatchInfo, KnockOutTournamentRound, Tournament}
import mrusanov.calendar.SeasonCalendar
import mrusanov.nation.Nation
import java.util.Date

class NationSeason(leagueInfoSystem:LeagueInfoSystem, val nation:Nation, year:Int) {
  private val calendar = new SeasonCalendar(year)
  private val cupRounds = 1
  private def clubs = Vector() ++ nation.clubs
  val firstTeamsLeagueSystem = LeagueSystem.initLeagueSystem(year, leagueInfoSystem, clubs, FirstTeam)
  val secondTeamsLeagueSystem = LeagueSystem.initLeagueSystem(year, leagueInfoSystem, clubs, SecondTeam)
  val juniorTeamsLeagueSystem = LeagueSystem.initLeagueSystem(year, leagueInfoSystem, clubs, JuniorTeam)
  var nationalCup = generateNationalCup

  val allTeams = clubs.map(_.teams).flatten

  def matchesByDate(date:Date):Vector[MatchInfo] = {
    val allLeagues = Vector(firstTeamsLeagueSystem, secondTeamsLeagueSystem, juniorTeamsLeagueSystem).map(_.leagues).flatten
    allLeagues.map(_.matchesByDate(date)).flatten
  }

  def league(team:Team) = {
    val leagueSystem = team.teamLevel match {
      case FirstTeam => firstTeamsLeagueSystem
      case SecondTeam => secondTeamsLeagueSystem
      case JuniorTeam => juniorTeamsLeagueSystem
    }

    leagueSystem.leagueOfTeam(team)
  }

  private def generateNationalCup:Tournament = {
    val roundsCount = biggestPowerOfTwoSmallerThanThisNumber(clubs.size)
    val dates = calendar.datesOfNationalCups(roundsCount)
    val builder = Vector.newBuilder[KnockOutTournamentRound]
    builder.sizeHint(roundsCount)
    var clubsCount = scala.math.pow(2, roundsCount).toInt
    for (i <- 0 until roundsCount) {
      builder += new KnockOutTournamentRound(clubsCount, cupRounds, dates.slice(i, i + 1))
      clubsCount /= 2
    }

    new Tournament("", builder.result())
  }

  private def biggestPowerOfTwoSmallerThanThisNumber(number:Int):Int = {
    var power = 0
    var rest = number
    while (rest != 1) {
      rest /= 2
      power += 1
    }

    power
  }
}
